''' Pykemon is an open-source game compatible with Python
    versions 2.2 and above, requires PyGame (tested with version 1.6.2,
    but probably works for a few older minor versions),
    and uses Psyco if it is available.
'''
try:
    import psyco
    psyco.full()
except ImportError:
    pass

import glob
import os
import pygame
import random
import sys

# local imports
import constants
import misc
import filed_objects
import modes
import network
import config

__doc__ += constants.STORYLINE
__version__ = 0

class Main(object):
    ''' container for such pygame objects as the screen, background surface, clock, etc.
        upon calling, enters a loop allowing transitioning from Mode to Mode.
    '''
    def __init__(self, player=None):
        ''' exports a global variable MAIN = self, allowing "pykelib.MAIN.player.sex = pykelib.constants.SEX_MALE"
        '''
        global MAIN
        MAIN = self
        pygame.init()
        pygame.font.init()
        pygame.mixer.init()
        self.audio = pygame.mixer.Channel()
        self.screen = pygame.display.set_mode(config.SCREEN)
        pygame.display.set_caption('Pykemon')
        pygame.mouse.set_visible(0)
        self.bg = pygame.Surface(self.screen.get_size()).convert()
        self.bg.fill(config.BG_COLOR)
        self.font = pygame.font.SysFont(*config.FONT)
        self.clock = pygame.time.Clock()
        self.player = player
        if misc.ipython: misc.start_daemon_thread(misc.ipython().mainloop)
    
    def __call__(self):
        ''' finite state machine.
            the state [an instance of a Mode subclass] is the result of calling the last Mode subclass instance.
        '''
        if self.player:
            self.mode = modes.Strolling(XXX)
        else:
            self.mode = self.try_update() or modes.AskSavedOrNew()()
        while self.mode is not constants.EXIT_MODE_LOOP:
            self.mode_start_time = time.time()
            new_mode = self.mode()
            if isinstance(self.mode, modes.GAME_TIME_MODES):
                self.player.game_time += config.GAME_TIME_RATE * (time.time() - self.mode_start_time)
            self.mode = new_mode
        return 0
    
    def quit(self):
        ''' conditionally asks if user really wants to quit, cleans up,
            then sets self.mode to indicate to the loop in __call__ to stop.
        '''
        do_quit = True
        if config.ASK_QUIT:
            # XXX set do_quit to user's choice
        if do_quit:
            self.mode = constants.EXIT_MODE_LOOP
    
    def try_update(self):
        ''' if pykelib.config.LATEST_VERSION_URL indicates that an update is available,
            return an Update Mode.
        '''
        try: latest_version = int(urllib.urlopen(pykelib.config.LATEST_VERSION_URL).read())
        except: return
        if latest_version > pykelib.__version__:
            return modes.Update(pykelib.config.UPDATE_URL % latest_version)
    

def main(argv, pyw_dir):
    ''' instantiate and call Main according to command line arguments.
    '''
    config.load(pyw_dir)
    if not os.path.isdir(config.SAVED_GAMES_DIRNAME):
        os.makedirs(config.SAVED_GAMES_DIRNAME, 0775)
    if ('-h' in argv) or ('--help' in argv):
        print constants.USAGE
        return 0
    else:
        try: player = Player(argv[0])
        except IOError: player = None
        return Main(player)()
